//
// Created by XUAN on 2024/8/23.
// IDF 5.2.1
// ADF 2.7.0
//
#include "main.h"
#include "esp_log.h"
#include "esp_heap_caps.h"
#include <esp_system.h>
#include <nvs_flash.h>
#include <audio_hal.h>
#include <audio_recorder.h>
#include <audio_service.h>
#include <audio_wrapper.h>
#include <board.h>
#include <circuit_board.h>
#include <esp_audio.h>
#include <esp_delegate.h>
#include <esp_dispatcher.h>
#include <esp_spiffs.h>
#include <esp_mac.h>
#include <esp_flash.h>
#include <periph_wifi.h>
#include <esp_netif.h>
#include <esp_psram.h>
// #include <extended_module.h>
#include <periph_spiffs.h>
#include "blufi_app.h"
#include "esp_peripherals.h"
#include "audio_tone_uri.h"
#include "app.h"


static const char *TAG = "MAIN";

/*----------------------blufi_app-------------------------*/
TaskHandle_t blufiAPPTaskHandle = NULL;
extern bool wifi_connected;
extern bool gl_sta_connected;
extern bool gl_sta_got_ip;
/*--------------------------------------------------------*/

/*---------------------------parameters------------------------------*/
char BT_MAC[35] = {0};
int msgId = 0;          // 消息ID
audio_board_handle_t board_handle = NULL;

static EventGroupHandle_t       chat_evt            = NULL;
static esp_audio_handle_t       player              = NULL;
static audio_rec_handle_t       recorder            = NULL;
/*------------------------------------------------------------------*/

extern "C"
{
void app_main(void);
};

// 挂载单个 SPIFFS 分区
esp_err_t mount_spiffs(const char *partition_label, const char *base_path) {
    esp_vfs_spiffs_conf_t conf = {
        .base_path = base_path,
        .partition_label = partition_label,
        .max_files = 5,
        .format_if_mount_failed = true
    };

    esp_err_t ret = esp_vfs_spiffs_register(&conf);
    if (ret != ESP_OK) {
        ESP_LOGE("SPIFFS", "Failed to mount partition %s", partition_label);
        return ret;
    }

    size_t total = 0, used = 0;
    ret = esp_spiffs_info(partition_label, &total, &used);
    if (ret != ESP_OK) {
        ESP_LOGE("SPIFFS", "Failed to get SPIFFS info for %s", partition_label);
        return ret;
    }
    ESP_LOGI("SPIFFS", "Partition %s mounted: total = %d, used = %d", partition_label, total, used);
    return ESP_OK;
}


static void retry_login_timer_cb(xTimerHandle tmr)
{
    ESP_LOGE(TAG, "Func:%s", __func__);
    // audio_service_connect(duer_serv_handle);
    xTimerStop(tmr, 0);
}

esp_err_t app_init_hal(void *instance, action_arg_t *arg, action_result_t *result)
{
    ESP_ERROR_CHECK(esp_netif_init());

    // Initialize peripherals management
    esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG();
    esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg);
    periph_spiffs_cfg_t spiffs_cfg = {
        .root = "/spiffs", // SPIFFS根目录
        .partition_label = "storage", // 分区标签
        .max_files = 5, // 最大文件数
        .format_if_mount_failed = true // 如果挂载失败则格式化
};
    esp_periph_handle_t spiffs_handle = periph_spiffs_init(&spiffs_cfg); // 初始化SPIFFS外围设备
    // 启动SPIFFS和按钮外围设备
    esp_periph_start(set, spiffs_handle); // 启动SPIFFS外围设备
    // 等待SPIFFS挂载
    while (!periph_spiffs_is_mounted(spiffs_handle)) { // 如果SPIFFS未挂载
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }

    audio_board_init();

    result->err = ESP_OK;
    return result->err;
}


void app_main(void)
{
    esp_log_level_set("*", ESP_LOG_INFO);

    ESP_LOGI("Compile time", "%s %s", __DATE__, __TIME__);
    ESP_LOGI(TAG, "[APP] Free memory: %ld bytes", esp_get_free_heap_size());
    ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
    size_t ram_left = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
    ESP_LOGW(TAG, "Internal ram left = %.2f KB, before init", (float)ram_left / 1024);
    ram_left = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
    ESP_LOGW(TAG, "SPI ram left = %.2f KB, before init", (float)ram_left / 1024);

    /* Initialize NVS. */
    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES ||
        err == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }
    ESP_ERROR_CHECK(err);

    uint8_t derived_mac_addr[6] = {0};
    ESP_ERROR_CHECK(esp_read_mac(derived_mac_addr, ESP_MAC_BT));
    sprintf(BT_MAC, "%02x:%02x:%02x:%02x:%02x:%02x", derived_mac_addr[0], derived_mac_addr[1], derived_mac_addr[2], derived_mac_addr[3], derived_mac_addr[4], derived_mac_addr[5]);


    circuit_board_init();

    app_chat();

}

